package middleware

import (
	"app/pkg/log"
	"bytes"
	"fmt"
	"net/http"
	"runtime"

	"github.com/gin-gonic/gin"
)

var (
	dunno     = []byte("???")
	centerDot = []byte("·")
	dot       = []byte(".")
	slash     = []byte("/")
)

func RecoverHandler() gin.HandlerFunc {
	logger := log.Logger()
	return func(c *gin.Context) {
		defer func() {
			if err := recover(); err != nil {
				if pc, file, line, ok := runtime.Caller(2); ok {
					logger.Errorf(c, fmt.Errorf("panic(%s) @ %s(%d)[%s]", err, file, line, function(pc)).Error())
				}
				//响应错误给用户
				c.AbortWithStatus(http.StatusInternalServerError)
			}
		}()
		c.Next()
	}
}

// function returns, if possible, the name of the function containing the PC.
func function(pc uintptr) []byte {
	fn := runtime.FuncForPC(pc)
	if fn == nil {
		return dunno
	}
	name := []byte(fn.Name())
	if lastslash := bytes.LastIndex(name, slash); lastslash >= 0 {
		name = name[lastslash+1:]
	}
	if period := bytes.Index(name, dot); period >= 0 {
		name = name[period+1:]
	}
	name = bytes.Replace(name, centerDot, dot, -1)
	return name
}
